package com.yunhe.policyfulfillment.policyful.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.model.mybatis.PageResult;
import com.yunhe.policyfulfillment.authority.domain.PolicyOrg;
import com.yunhe.policyfulfillment.authority.domain.PolicyUser;
import com.yunhe.policyfulfillment.authority.repository.IPolicyOrgRepository;
import com.yunhe.policyfulfillment.authority.repository.IPolicyUserRepository;
import com.yunhe.policyfulfillment.authority.service.IPolicyOrgService;
import com.yunhe.policyfulfillment.authority.service.IPolicyUserService;
import com.yunhe.policyfulfillment.constant.PolicyFulfillmentConstant;
import com.yunhe.policyfulfillment.policyful.domain.Annex;
import com.yunhe.policyfulfillment.policyful.domain.Appeal;
import com.yunhe.policyfulfillment.policyful.domain.AppealProcess;
import com.yunhe.policyfulfillment.policyful.model.AppealCondition;
import com.yunhe.policyfulfillment.policyful.model.AppealStatistic;
import com.yunhe.policyfulfillment.policyful.model.AppealVO;
import com.yunhe.policyfulfillment.policyful.model.AppealView;
import com.yunhe.policyfulfillment.policyful.repository.AnnexRepository;
import com.yunhe.policyfulfillment.policyful.repository.AppealProcessRepository;
import com.yunhe.policyfulfillment.policyful.repository.AppealRepository;
import com.yunhe.policyfulfillment.policyful.service.AppealService;
import com.yunhe.policyfulfillment.policyful.service.SerialNumService;
import com.yunhe.policyfulfillment.util.MyHeaderUtil;
import com.yunhe.policyfulfillment.util.SmsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yunhe.common.util.CollectionUtil;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @ClassName: AppealServiceImpl
 * @Description:
 * @author: GongDaCheng
 * @Date: 14:33 2021/8/24
 */
@Service
public class AppealServiceImpl implements AppealService {

    @Autowired
    AppealRepository appealRepository;

    @Autowired
    AnnexRepository annexRepository;

    @Autowired
    AppealProcessRepository appealProcessRepository;

    @Autowired
    SerialNumService serialNumService;

    @Autowired
    private MyHeaderUtil myHeaderUtil;

    @Autowired
    private IPolicyOrgRepository iPolicyOrgRepository;

    @Autowired
    private IPolicyUserService iPolicyUserService;

    @Override
    public int createAppeal(AppealVO appealVO) {
        Appeal appeal = new Appeal();
        //BeanUtils.copyProperties(appeal, appealVO);
        appeal.setAppealCategory(appealVO.getAppealCategory());
        appeal.setAppealContent(appealVO.getAppealContent());
        appeal.setAppealPersonContact(appealVO.getAppealPersonContact());
        appeal.setAppealPersonName(appealVO.getAppealPersonName());
        appeal.setAppealTitle(appealVO.getAppealTitle());
        appeal.setAppealType(appealVO.getAppealType());
        //设置是否删除为未删除
        appeal.setIsDelete("0");
        //设置是否公开为不公开
        appeal.setIsPublic("2");
        //设置处理部门为党政办
        List<PolicyOrg> partyGovernmentOffice = iPolicyOrgRepository.findPolicyOrgsByOrgType(PolicyFulfillmentConstant.OrgType.PartyGovernmentOffice.value());
        appeal.setHandleOrg(partyGovernmentOffice.get(0).getId());
        //设置提交日期
        appeal.setSubmitTime(new Date());
        //设置办理状态为待分发
        appeal.setHandleState(PolicyFulfillmentConstant.Handle_State.ToBeDistributed.value());
        //设置诉求编码
        String appealCode = serialNumService.generateSerialNumberByModelCode("SQ");
        appeal.setAppealCode(appealCode);
        int count = appealRepository.createAppeal(appeal);
        //为附件appealId赋值
        long appealId = appeal.getId();
        List<Annex> annexList = appealVO.getAnnexList();
        if (annexList != null){
            for (Annex annex : annexList) {
                annex.setAppealId(appealId);
                annexRepository.createAnnex(annex);
            }
        }
        return count;
    }

    @Override
    public int deleteAppeal(int id) throws ArgumentErrorException {
        PolicyUser headerUser = myHeaderUtil.getHeaderUser();
        if (!PolicyFulfillmentConstant.Role_Name.Admin.value().equals(headerUser.getRoleName())){
            throw new ArgumentErrorException("只有管理员才能进行删除操作，您无权进行删除操作！");
        }
        return appealRepository.deleteAppeal(id);
    }

    @Override
    public int updateAppeal(Appeal appeal) {
        return appealRepository.updateAppeal(appeal);
    }

    @Override
    public Appeal findAppealById(long id) {
        return appealRepository.findAppealById(id);
    }

    @Override
    public AppealStatistic getAppealStatistic() throws ParseException {
        AppealStatistic appealStatistic = new AppealStatistic();
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        int year = cal.get(Calendar.YEAR);
        //获取startTime和EndTime进行筛选
        String yearStr = String.valueOf(year);
        String startTimeStr = yearStr + "-01-01 00:00:00";
        String endTimeStr = yearStr + "-12-31 23:59:59";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startTime = sdf.parse(startTimeStr);
        Date endTime = sdf.parse(endTimeStr);
        int annualTotalCount = appealRepository.getAnnualTotalCount(startTime, endTime);
        int annualHandledCount = appealRepository.getAnnualHandledCount(startTime, endTime);
        int annualUntreatedCount = appealRepository.getAnnualUntreated(startTime, endTime);
        appealStatistic.setAnnualTotalCount(annualTotalCount);
        appealStatistic.setHandledCount(annualHandledCount);
        appealStatistic.setUntreatedCount(annualUntreatedCount);
        return appealStatistic;
    }

    @Override
    public PageResult getAppealByCondition(AppealCondition appealCondition) throws ParseException {
        PageResult result = null;
        PolicyUser headerUser = myHeaderUtil.getHeaderUser();
        appealCondition.setCurrentUserOrg(Long.valueOf(headerUser.getOrgId()));
        //如果筛选条件里的处理部门为空，该次查询为查询全部，此时对主管部门获取的列表做限制（只能看自己部门的数据）
        if (appealCondition.getHandleOrg() == null){
            //如果当前登陆账号部门是主管部门，则只可以查看自己部门数据
            if (PolicyFulfillmentConstant.Role_Name.SupervisorOrg.value().equals(headerUser.getRoleName())){
                appealCondition.setHandleOrg(Long.valueOf(headerUser.getOrgId()));
            }
            /*//如果当前登陆账号部门不是党政办，则只可以查看自己部门数据
            if (!PolicyFulfillmentConstant.OrgType.PartyGovernmentOffice.value().equals(headerUser.getRoleName())){
                //如果是管理员，则将handleOrg设置为null
                if (PolicyFulfillmentConstant.Role_Name.Admin.value().equals(headerUser.getRoleName())){
                    appealCondition.setHandleOrg(null);
                }
                appealCondition.setHandleOrg(Long.valueOf(headerUser.getOrgId()));
            }*/
        }
        PageHelper.startPage(appealCondition.getPage(), appealCondition.getSize());
        List<Appeal> appeals = appealRepository.getAppealByCondition(appealCondition);
        for (Appeal appeal : appeals) {
            Date deadLine = appeal.getDeadLine();
            if (deadLine != null){
                Date now = new Date();
                appeal.setRemainingDays(daysBetween(now, deadLine));
                updateAppeal(appeal);
            }
            if (appeal.getHandleOrg() != 0){
                PolicyOrg policyOrg = iPolicyOrgRepository.searchPolicyOrgByPrimaryKey((int) appeal.getHandleOrg());
                appeal.setHandleOrgTitle(policyOrg.getOrgName());
            }
        }
        PageInfo<Appeal> pageInfo = new PageInfo<>(appeals);
        result = new PageResult(appealCondition.getPage(), appealCondition.getSize(), (int)pageInfo.getTotal(), appeals);
        return result;
    }

    @Override
    public PageResult getAppealByConditionPortal(AppealCondition appealCondition) throws ParseException {
        PageResult result = null;
        PageHelper.startPage(appealCondition.getPage(), appealCondition.getSize());
        List<Appeal> appeals = appealRepository.getAppealByConditionPortal(appealCondition);
        for (Appeal appeal : appeals) {
            Date deadLine = appeal.getDeadLine();
            if (deadLine != null){
                Date now = new Date();
                appeal.setRemainingDays(daysBetween(now, deadLine));
                updateAppeal(appeal);
            }
            if (appeal.getHandleOrg() != 0){
                PolicyOrg policyOrg = iPolicyOrgRepository.searchPolicyOrgByPrimaryKey((int) appeal.getHandleOrg());
                appeal.setHandleOrgTitle(policyOrg.getOrgName());
            }
        }
        PageInfo<Appeal> pageInfo = new PageInfo<>(appeals);
        result = new PageResult(appealCondition.getPage(), appealCondition.getSize(), (int)pageInfo.getTotal(), appeals);
        return result;
    }


    @Override
    public void publicAppeal(long id) {
        appealRepository.publicAppeal(id);
    }

    @Override
    public void distributeAppeal(long appealId, long handleOrg, Date deadLine) throws ArgumentErrorException {
        PolicyUser headerUser = myHeaderUtil.getHeaderUser();
        if(headerUser == null){
            throw new ArgumentErrorException("用户登录信息已过期，请重新登录！");
        }
        Appeal appeal = appealRepository.findAppealById(appealId);
        if (PolicyFulfillmentConstant.Handle_State.ToBeDistributed.value().equals(appeal.getHandleState())) {
            appeal.setHandleOrg(handleOrg);
            appeal.setDeadLine(deadLine);
            appeal.setHandleState(PolicyFulfillmentConstant.Handle_State.Todo.value());
            appealRepository.updateAppeal(appeal);

            AppealProcess appealProcess = new AppealProcess();
            appealProcess.setAppealId(appealId);
            //分发时处理部门为党政办
            appealProcess.setHandleOrg(headerUser.getOrgId());
            if (appeal.getHandleOrg() != 0){
                PolicyOrg handleOrgObj = iPolicyOrgRepository.searchPolicyOrgByPrimaryKey((int) appeal.getHandleOrg());
                appealProcess.setHandleOrgTitle(handleOrgObj.getOrgName());
            }
            appealProcess.setCreateTime(new Date());
            appealProcess.setDeadline(deadLine);
            //移交部门
            appealProcess.setHandoverOrg(handleOrg);
            PolicyOrg handoverOrgObj = iPolicyOrgRepository.searchPolicyOrgByPrimaryKey((int) handleOrg);
            appealProcess.setHandoverOrgTitle(handoverOrgObj.getOrgName());
            //设置办理状态为待处理
            appealProcess.setStatus(PolicyFulfillmentConstant.Handle_State.Todo.value());
            appealProcessRepository.createAppealProcess(appealProcess);
        } else if (PolicyFulfillmentConstant.Handle_State.Todo.value().equals(appeal.getHandleState())){
            throw new ArgumentErrorException("该诉求当前已分发，请勿重复分发！");
        }else if (PolicyFulfillmentConstant.Handle_State.Handled.value().equals(appeal.getHandleState())){
            throw new ArgumentErrorException("该诉求当前已处理，无法进行分发操作！");
        }else if (PolicyFulfillmentConstant.Handle_State.termination.value().equals(appeal.getHandleState())){
            throw new ArgumentErrorException("该诉求当前已中止，无法进行分发操作！");
        }
    }

    @Override
    public AppealView viewAppealById(long appealId) {
        AppealView appealView = new AppealView();
        Appeal appeal = appealRepository.findAppealById(appealId);
        appealView.setAppealType(appeal.getAppealType());
        appealView.setAppealCategory(appeal.getAppealCategory());
        appealView.setAppealTitle(appeal.getAppealTitle());
        appealView.setAppealPersonName(appeal.getAppealPersonName());
        appealView.setAppealPersonContact(appeal.getAppealPersonContact());
        appealView.setAppealContent(appeal.getAppealContent());
        appealView.setAnnexList(annexRepository.findAnnexByAppealId(appealId));
        appealView.setSubmitTime(appeal.getSubmitTime());
        appealView.setIsPublic(appeal.getIsPublic());
        appealView.setHandleState(appeal.getHandleState());
        List<AppealProcess> appealProcesses = appealProcessRepository.findByAppealId(appealId);
        for (AppealProcess appealProcess : appealProcesses) {
            if (appealProcess.getHandleOrg() != 0){
                PolicyOrg policyOrg = iPolicyOrgRepository.searchPolicyOrgByPrimaryKey((int) appealProcess.getHandleOrg());
                appealProcess.setHandleOrgTitle(policyOrg.getOrgName());
            }
            if (appealProcess.getHandoverOrg() != 0){
                PolicyOrg policyOrg = iPolicyOrgRepository.searchPolicyOrgByPrimaryKey((int) appealProcess.getHandoverOrg());
                appealProcess.setHandoverOrgTitle(policyOrg.getOrgName());
            }
        }
        appealView.setAppealProcessList(appealProcesses);
        return appealView;
    }

    /*@Override
    public void handleAppeal(long appealId, String suggest, String targetStatus) throws ArgumentErrorException {
        PolicyUser headerUser = myHeaderUtil.getHeaderUser();
        if(headerUser == null){
            throw new ArgumentErrorException("用户登录信息已过期，请重新登录！");
        }
        Appeal appeal = appealRepository.findAppealById(appealId);
        //判断当前账号的部门角色是否和待处理部门相同
        PolicyOrg policyOrg = iPolicyOrgRepository.searchPolicyOrgByPrimaryKey(headerUser.getOrgId());
        if (appeal.getHandleOrg() != (long) headerUser.getOrgId()){
            throw new ArgumentErrorException("当前诉求不属于" + policyOrg.getOrgName() + "的处理范畴，请选择其他诉求进行处理！");
        }
        //判断当前诉求的状态，只有为”待处理“才能进行处理操作
        if (PolicyFulfillmentConstant.Handle_State.Todo.value().equals(appeal.getHandleState())){
            if (PolicyFulfillmentConstant.Handle_State.ToBeDistributed.value().equals(targetStatus)){
                //如果为退回，状态为待分发，处理部门设置为党政办
                List<PolicyOrg> partyGovernmentOffice = iPolicyOrgRepository.findPolicyOrgsByOrgType(PolicyFulfillmentConstant.OrgType.PartyGovernmentOffice.value());
                appeal.setHandleOrg(partyGovernmentOffice.get(0).getId());
            }else {
                //如果为回复和中止，处理部门为当前部门
                appeal.setHandleOrg(headerUser.getOrgId());
            }
            appeal.setHandleTime(new Date());
            appeal.setHandleState(targetStatus);
            appealRepository.updateAppeal(appeal);

            AppealProcess appealProcess = new AppealProcess();
            appealProcess.setAppealId(appealId);
            appealProcess.setHandleOrg(headerUser.getOrgId());
            appealProcess.setHandleComment(suggest);
            appealProcess.setCreateTime(new Date());
            appealProcess.setStatus(targetStatus);
            appealProcessRepository.createAppealProcess(appealProcess);
        } else if (PolicyFulfillmentConstant.Handle_State.Handled.value().equals(appeal.getHandleState())) {
            throw new ArgumentErrorException("当前诉求状态为已处理，无法再进行处理操作！");
        }else if (PolicyFulfillmentConstant.Handle_State.ToBeDistributed.value().equals(appeal.getHandleState())){
            if (PolicyFulfillmentConstant.Role_Name.SupervisorOrg.value().equals(headerUser.getRoleName())){
                throw new ArgumentErrorException("当前诉求还未进行分发，无法进行处理操作！");
            }
        }else if (PolicyFulfillmentConstant.Handle_State.termination.value().equals(appeal.getHandleState())){
            throw new ArgumentErrorException("当前诉求已中止，无法进行处理操作！");
        } else {
            throw new ArgumentErrorException("诉求状态异常！");
        }
    }*/

    @Override
    public void handleAppeal(long appealId, String suggest, String targetStatus) throws ArgumentErrorException {
        PolicyUser headerUser = myHeaderUtil.getHeaderUser();
        if(headerUser == null){
            throw new ArgumentErrorException("用户登录信息已过期，请重新登录！");
        }
        Appeal appeal = appealRepository.findAppealById(appealId);
        //登陆账号为党政办账号
        if (PolicyFulfillmentConstant.Role_Name.PartyGovernmentOffice.value().equals(headerUser.getRoleName())){
            //判断当前账号的部门角色是否和诉求的待处理部门相同
            if (appeal.getHandleOrg() != (long) headerUser.getOrgId() &&
                    PolicyFulfillmentConstant.Handle_State.Handled.value().equals(targetStatus)){
                PolicyOrg handleOrgObj = iPolicyOrgRepository.searchPolicyOrgByPrimaryKey((int) appeal.getHandleOrg());
                throw new ArgumentErrorException("当前诉求已分发给" + handleOrgObj.getOrgName() + "进行处理！");
            }
            //对于党政办状态为待分发和待处理能进行中止操作
            if (PolicyFulfillmentConstant.Handle_State.ToBeDistributed.value().equals(appeal.getHandleState()) ||
                    PolicyFulfillmentConstant.Handle_State.Todo.value().equals(appeal.getHandleState())){
                //如果状态为待处理，不能进行回复操作
                if (PolicyFulfillmentConstant.Handle_State.Handled.value().equals(targetStatus) &&
                    PolicyFulfillmentConstant.Handle_State.Todo.value().equals(appeal.getHandleState())){
                    throw new ArgumentErrorException("待处理状态下党政办不能进行回复！");
                }
                //更新诉求
                appeal.setHandleTime(new Date());
                appeal.setHandleOrg((long) headerUser.getOrgId());
                appeal.setHandleState(targetStatus);
                appealRepository.updateAppeal(appeal);

                //创建状态流程信息
                AppealProcess appealProcess = new AppealProcess();
                appealProcess.setAppealId(appealId);
                appealProcess.setHandleOrg(headerUser.getOrgId());
                appealProcess.setHandleComment(suggest);
                appealProcess.setCreateTime(new Date());
                appealProcess.setStatus(targetStatus);
                appealProcessRepository.createAppealProcess(appealProcess);
            }else {
                throw new ArgumentErrorException("该诉求已处理或已中止，无法进行处理操作！");
            }
        }
        //登陆账号为主管部门账号
        else if (PolicyFulfillmentConstant.Role_Name.SupervisorOrg.value().equals(headerUser.getRoleName())){
            //对于主管部门只有状态为待处理才能进行处理操作（回复和退回）
            if (PolicyFulfillmentConstant.Handle_State.Todo.value().equals(appeal.getHandleState())){
                appeal.setHandleTime(new Date());
                appeal.setHandleOrg((long) headerUser.getOrgId());
                appeal.setHandleState(targetStatus);
                appealRepository.updateAppeal(appeal);

                //创建状态流程信息
                AppealProcess appealProcess = new AppealProcess();
                appealProcess.setAppealId(appealId);
                appealProcess.setHandleOrg(headerUser.getOrgId());
                appealProcess.setHandleComment(suggest);
                appealProcess.setCreateTime(new Date());
                appealProcess.setStatus(targetStatus);
                appealProcessRepository.createAppealProcess(appealProcess);
            }else{
                throw new ArgumentErrorException("该诉求已处理或已中止，无法进行处理操作！");
            }
        }
    }

    @Override
    public void urgeAppeal(long appealId) throws ArgumentErrorException {
        Appeal appeal = appealRepository.findAppealById(appealId);
        //判断当前状态，当前状态为待分发、已处理、中止时，不能进行催办操作
        if (PolicyFulfillmentConstant.Handle_State.Handled.value().equals(appeal.getHandleState()) ||
                PolicyFulfillmentConstant.Handle_State.termination.value().equals(appeal.getHandleState()) ||
                PolicyFulfillmentConstant.Handle_State.ToBeDistributed.value().equals(appeal.getHandleState())){
            throw new ArgumentErrorException("诉求目前状态为待分发、已处理、中止，不能进行催办操作！");
        }
        long currentHandleOrg = appeal.getHandleOrg();
        List<PolicyUser> policyUsers = iPolicyUserService.findPolicyUsersByOrgId((int) currentHandleOrg);
        /*if (!CollectionUtil.isEmpty(policyUsers)){
            //发送短信通知
            for (PolicyUser policyUser : policyUsers) {
                HashMap<String, String> map = new HashMap<>();
                map.put("code", appeal.getAppealCode());
                String templateCode = "SMS_223200181";
                String templateParam = "{\"code\":\"" + appeal.getAppealCode() + "\"}";
                try {
                    SmsUtil.sendSms(policyUser.getPhone(), map, templateCode, templateParam);
                } catch (Exception e) {
                    throw new ArgumentErrorException("短信发送失败！");
                }
            }
        }*/

    }

    /**
     * 计算两个日期之间相差的天数
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate,Date bdate) throws ParseException
    {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        smdate=sdf.parse(sdf.format(smdate));
        bdate=sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

        return Integer.parseInt(String.valueOf(between_days));
    }
}
